home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / ax25hdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  2.6 KB  |  113 lines

  1. /* @(#) $Header: ax25hdr.c,v 1.2 91/02/24 20:16:33 deyke Exp $ */
  2.  
  3. /* AX25 header conversion routines
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9.  
  10. /* Convert a host-format AX.25 header into a mbuf ready for transmission */
  11. struct mbuf *
  12. htonax25(hdr,data)
  13. register struct ax25 *hdr;
  14. struct mbuf *data;
  15. {
  16.     struct mbuf *bp;
  17.     register char *cp;
  18.     register int16 i;
  19.  
  20.     if(hdr == (struct ax25 *)NULL || hdr->ndigis > MAXDIGIS)
  21.         return NULLBUF;
  22.  
  23.     /* Allocate space for return buffer */
  24.     i = AXALEN * (2 + hdr->ndigis);
  25.     if((bp = pushdown(data,i)) == NULLBUF)
  26.         return NULLBUF;
  27.  
  28.     /* Now convert */
  29.     cp = bp->data;          /* cp -> dest field */
  30.  
  31.     /* Generate destination field */
  32.     memcpy(cp,hdr->dest,AXALEN);
  33.     if(hdr->cmdrsp == LAPB_COMMAND)
  34.         cp[ALEN] |= C;  /* Command frame sets C bit in dest */
  35.     else
  36.         cp[ALEN] &= ~C;
  37.     cp[ALEN] &= ~E; /* Dest E-bit is always off */
  38.  
  39.     cp += AXALEN;           /* cp -> source field */
  40.  
  41.     /* Generate source field */
  42.     memcpy(cp,hdr->source,AXALEN);
  43.     if(hdr->cmdrsp == LAPB_RESPONSE)
  44.         cp[ALEN] |= C;
  45.     else
  46.         cp[ALEN] &= ~C;
  47.     /* Set E bit on source address if no digis */
  48.     if(hdr->ndigis == 0){
  49.         cp[ALEN] |= E;
  50.         return bp;
  51.     } else
  52.         cp[ALEN] &= ~E;
  53.  
  54.     cp += AXALEN;           /* cp -> first digi field */
  55.  
  56.     /* All but last digi get copied with E bit off */
  57.     for(i=0; i < hdr->ndigis; i++){
  58.         memcpy(cp,hdr->digis[i],AXALEN);
  59.         if(i < hdr->ndigis - 1)
  60.             cp[ALEN] &= ~E;
  61.         else
  62.             cp[ALEN] |= E;  /* Last digipeater has E bit set */
  63.         if(i < hdr->nextdigi)
  64.             cp[ALEN] |= REPEATED;
  65.         else
  66.             cp[ALEN] &= ~REPEATED;
  67.         cp += AXALEN;           /* cp -> next digi field */
  68.     }
  69.     return bp;
  70. }
  71. /* Convert a network-format AX.25 header into a host format structure
  72.  * Return -1 if error, number of addresses if OK
  73.  */
  74. int
  75. ntohax25(hdr,bpp)
  76. register struct ax25 *hdr;      /* Output structure */
  77. struct mbuf **bpp;
  78. {
  79.     register char *axp;
  80.  
  81.     if(pullup(bpp,hdr->dest,AXALEN) < AXALEN)
  82.         return -1;
  83.  
  84.     if(pullup(bpp,hdr->source,AXALEN) < AXALEN)
  85.         return -1;
  86.  
  87.     /* Process C bits to get command/response indication */
  88.     if((hdr->source[ALEN] & C) == (hdr->dest[ALEN] & C))
  89.         hdr->cmdrsp = LAPB_UNKNOWN;
  90.     else if(hdr->source[ALEN] & C)
  91.         hdr->cmdrsp = LAPB_RESPONSE;
  92.     else
  93.         hdr->cmdrsp = LAPB_COMMAND;
  94.  
  95.     hdr->ndigis = 0;
  96.     hdr->nextdigi = 0;
  97.     if(hdr->source[ALEN] & E)
  98.         return 2;       /* No digis */
  99.  
  100.     /* Count and process the digipeaters */
  101.     axp = hdr->digis[0];
  102.     while(hdr->ndigis < MAXDIGIS && pullup(bpp,axp,AXALEN) == AXALEN){
  103.         hdr->ndigis++;
  104.         if(axp[ALEN] & REPEATED)
  105.             hdr->nextdigi++;
  106.         if(axp[ALEN] & E)       /* Last one */
  107.             return hdr->ndigis + 2;
  108.         axp += AXALEN;
  109.     }
  110.     return -1;      /* Too many digis */
  111. }
  112.  
  113.